package com.glsc.ngateway.opmanage.controller.report;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.base.domain.mysql.opmanage.report.FileUploadLog;
import com.glsc.ngateway.common.base.dto.opmanage.report.DerivativeResponse;
import com.glsc.ngateway.common.base.repo.mysql.opmanage.report.FileUploadLogRepository;
import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.opmanage.aspect.JwtHelper;
import com.glsc.ngateway.opmanage.service.UserService;
import com.glsc.ngateway.opmanage.service.report.FileUploadService;
import com.glsc.ngateway.opmanage.utils.SpecificationFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("api/fileUpload")
@EnableAutoConfiguration(exclude={MultipartAutoConfiguration.class})
@Api(value = "文件上传controller", tags = {"文件上传接口"})
public class FileUploadController {
    @Autowired
    private FileUploadService fileUploadService;

    @Autowired
    private FileUploadLogRepository fileUploadLogRepository;

    @Autowired
    private UserService userService;

    @Value("${opmanage.nas.path.zyfile}")
    String nasPath = "";

    @ApiOperation(value = "上传")
    @PostMapping("/upload")
    public DerivativeResponse upload(@RequestParam(required=false,value="files") MultipartFile[] files, HttpServletRequest request) throws IllegalStateException, IOException, JSONException {
        try {
            if(files.length > 0){
                String userName="";
                String token=request.getHeader("token");
                if(userService.isInvokeGatewaySSO(token,"token")){
                    userName=userService.getIdFromToken(token);
                }else{
                    userName= JwtHelper.parseToken(token).trim();
                }
                String time=LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                String path = time+"/"+uuid;
                //定义文件
                File parent = new File(path);
                if(!parent.exists()) parent.mkdirs();

                HashMap<String, String> ret = new HashMap<>();
                List<String> typeList=new ArrayList<>();
                typeList.add(".exe");
                typeList.add(".dll");
                //循环多次上传多个文件
                for (MultipartFile tmp : files) {
                    String id = UUID.randomUUID().toString().replaceAll("-", "");
                    String filename = tmp.getOriginalFilename();
                    byte[] fileByte=tmp.getBytes();
                    int potIndex = filename.lastIndexOf(".");
                    String type = potIndex < 0 ? "" : filename.substring(potIndex);

                    if(typeList.contains(type)){
                        ret.put(filename, DerivativeResponse.error("失败",ret).toString());
                    }else{
                        tmp.transferTo(new File(parent, filename));

                        FileUploadLog fileUploadLog=new FileUploadLog();
                        fileUploadLog.setId(id);
                        fileUploadLog.setUploadTime(LocalDateTime.now());
                        fileUploadLog.setUserName(userName);
                        fileUploadLog.setFileName(filename);
                        fileUploadLog.setPath(path+"/"+filename);
                        fileUploadLog.setFile(fileByte);
                        fileUploadService.saveUploadLog(fileUploadLog);

                        JSONObject fileinfo=new JSONObject();
                        fileinfo.put("id",id);
                        fileinfo.put("username",userName);
                        fileinfo.put("filename",filename);
                        fileinfo.put("time",fileUploadLog.getUploadTime());
                        ret.put(filename,fileinfo.toJSONString());
                    }

                }

                //以json方式输出到页面
                return DerivativeResponse.success("成功",ret);
            }else{
                return DerivativeResponse.success("文件列表为空",files.length);
            }

        }catch(Exception e) {
            return DerivativeResponse.error("错误",e.getMessage());
        }
    }

    @ApiOperation(value = "单文件上传")
    @PostMapping("/singleFileUpload")
    public DerivativeResponse upload(@RequestParam(required=false,value="file") MultipartFile file, HttpServletRequest request) throws IllegalStateException, IOException, JSONException {
        try {
            if(!file.isEmpty()){
                String userName="";
                String token=request.getHeader("token");
                if(userService.isInvokeGatewaySSO(token,"token")){
                    userName=userService.getIdFromToken(token);
                }else{
                    userName=JwtHelper.parseToken(token).trim();
                }
                String time=LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                String path = nasPath + time+"/"+uuid;
                //定义文件
                File parent = new File(path);
                if(!parent.exists()) parent.mkdirs();

                HashMap<String, String> ret = new HashMap<>();
                List<String> typeList=new ArrayList<>();
                typeList.add(".exe");
                typeList.add(".dll");
                String id = UUID.randomUUID().toString().replaceAll("-", "");
                String filename = file.getOriginalFilename();
                byte[] fileByte=file.getBytes();
                int potIndex = filename.lastIndexOf(".");
                String type = potIndex < 0 ? "" : filename.substring(potIndex);

                if(typeList.contains(type)){
                    ret.put(filename,"type forbiden");
                    return DerivativeResponse.error("失败",ret);
                }else{
                    file.transferTo(new File(parent, filename));

                    FileUploadLog fileUploadLog=new FileUploadLog();
                    fileUploadLog.setId(id);
                    fileUploadLog.setUploadTime(LocalDateTime.now());
                    fileUploadLog.setUserName(userName);
                    fileUploadLog.setFileName(filename);
                    fileUploadLog.setPath(path+"/"+filename);
                    fileUploadLog.setFile(fileByte);
                    fileUploadService.saveUploadLog(fileUploadLog);

                    JSONObject fileinfo=new JSONObject();
                    fileinfo.put("id",id);
                    fileinfo.put("username",userName);
                    fileinfo.put("filename",filename);
                    fileinfo.put("time",fileUploadLog.getUploadTime());
                    ret.put(filename,fileinfo.toJSONString());
                }

                //以json方式输出到页面
                return DerivativeResponse.success("成功",ret);
            }else{
                return DerivativeResponse.success("文件为空",null);
            }

        }catch(Exception e) {
            return DerivativeResponse.error("错误",e.getMessage());
        }
    }

    @GetMapping("/listpage")
    @ApiOperation(value = "查询用户分页")
    public DerivativeResponse listpage(
            @ApiParam(value = "登录账号") @RequestParam(required = false) String username,
            @ApiParam(value = "用户名字") @RequestParam(required = false) String uploadTime,
            @ApiParam(value = "客户编号") @RequestParam(required = false) String id,
            @ApiParam(value = "用户类型") @RequestParam(required = false) String filename,
            @ApiParam(value = "页码从1开始") @RequestParam(required = false) Integer pageNo,
            @ApiParam(value = "每页显示条数 默认10") @RequestParam(required = false) Integer pageSize) {
        if (username != null && username.isEmpty()) {
            username = null;
        }
        if (uploadTime != null && uploadTime.isEmpty()) {
            uploadTime = null;
        }
        if (id != null && id.isEmpty()) {
            id = null;
        }
        if (filename != null && filename.isEmpty()) {
            filename = null;
        }


        SpecificationFactory.SpecElement usernameE = new SpecificationFactory.SpecElement(SpecificationFactory.Type.LIKE, "userName", username);
        SpecificationFactory.SpecElement uploadTimeE = new SpecificationFactory.SpecElement(SpecificationFactory.Type.LIKE, "uploadTime", uploadTime);
        SpecificationFactory.SpecElement idE = new SpecificationFactory.SpecElement(SpecificationFactory.Type.EQ, "id", id);
        SpecificationFactory.SpecElement fileNameE = new SpecificationFactory.SpecElement(SpecificationFactory.Type.LIKE, "fileName", filename);
        Specification spec = SpecificationFactory.build(SpecificationFactory.OP.AND, usernameE, uploadTimeE, idE, fileNameE);
        Sort sortRule=Sort.by(Sort.Order.desc("id"), Sort.Order.asc("uploadTime"), Sort.Order.asc("userName"), Sort.Order.asc("fileName"));
        Page page = SpecificationFactory.findPageParams(spec, sortRule, PageUtil.initPageNo(pageNo),
                PageUtil.initPageSize(pageSize), fileUploadLogRepository);

        return DerivativeResponse.success(page);
    }

    @PostMapping("/download")
    @ApiOperation(value = "文件下载")
    public DerivativeResponse download(@ApiParam(value = "基础持仓信息") @RequestBody FileUploadLog fileUploadLog,
                                       HttpServletResponse response) throws IOException {
        String id=fileUploadLog.getId();
        FileUploadLog fileInfo = fileUploadLogRepository.getById(id);
        String fileName=fileInfo.getFileName();
        String path=fileInfo.getPath();
        File file=new File(path);
        if(file.exists()){
            response.addHeader("Content-Length", "" + file.length());
            InputStream in = new FileInputStream(path);
            int len = 0;

            byte[] buffer = new byte[1024];
            response.reset();
            response.setHeader("Content-Disposition", fileName);//设置文件名
            OutputStream outputStream = response.getOutputStream();
            while ((len = in.read(buffer)) > 0) {

                outputStream.write(buffer, 0, len);
            }
            outputStream.flush();
        }else{
            byte[] out=fileInfo.getFile();
            OutputStream local=new FileOutputStream(path);
            local.write(out);
            local.flush();
            response.reset();
            response.setHeader("Content-Disposition", fileName);//设置文件名
            OutputStream output = response.getOutputStream();
            output.write(out);
            output.flush();
        }
        return DerivativeResponse.success("下载成功");
    }
}
